#!/usr/bin/perl

#===============================================================================
#     REVISION:  $Id$
#  DESCRIPTION:  Simple workflow test: create several users, houses, appartments,
#                add meterings, find a user with all user's data objects etc.
#===============================================================================

use strict;
use warnings;

use Readonly;
Readonly our $VERSION => qw($Revision$) [1];

use English qw( -no_match_vars );

#use Smart::Comments;
#$ENV{'DONT_CLEANUP'} = 1;

use Meter::Test qw(
    init_tmp_db
);

use Meter::Users;
use Meter::Houses;
use Meter::Appartments;
use Meter::Meterings;

use Meter::Utils qw(
    dump_compact
);

use Test::More tests => 7;
use Test::Exception;
use Test::DatabaseRow;

sub test_common_case {
    my $house1 = Meter::Houses->insert(
        { address => 'Коломяжский пр-т 15-1' } );

    my $house2 = Meter::Houses->insert(
        { address => 'Коломяжский пр-т 15-2' } );

    my $user1 = Meter::Users->insert(
        {   username => 'user1',
            password => 'password1',
            email    => 'email1@example.com',
        }
    );

    my $user2 = Meter::Users->insert(
        {   username => 'user2',
            password => 'password2',
            email    => 'email2@example.com',
        }
    );

    my $user3 = Meter::Users->insert(
        {   username => 'user3',
            password => 'password3',
            email    => 'email3@example.com',
        }
    );

    my $appartment1 = Meter::Appartments->insert(
        {   user                    => $user1,
            house                   => $house1,
            appartment_number       => '11',
            first_name              => 'Имя1',
            last_name               => 'Фамилия1',
            middle_name             => 'Отчество1',
            cold_water_meter_number => '100001',
            hot_water_meter_number  => '200001',
        }
    );

    my $appartment2 = Meter::Appartments->insert(
        {   user                    => $user2,
            house                   => $house1,
            appartment_number       => '22',
            first_name              => 'Имя2',
            last_name               => 'Фамилия2',
            middle_name             => 'Отчество2',
            cold_water_meter_number => '100002',
            hot_water_meter_number  => '200002',
        }
    );

    my $appartment3 = Meter::Appartments->insert(
        {   user                    => $user3,
            house                   => $house2,
            appartment_number       => '33',
            first_name              => 'Имя3',
            last_name               => 'Фамилия3',
            middle_name             => 'Отчество3',
            cold_water_meter_number => '100003',
            hot_water_meter_number  => '200003',
        }
    );

    my $metering_fields = {};

    # user1's meterings
    my $metering11 = Meter::Meterings->insert(
        {   appartment              => $appartment1,
            start_date              => '2011-05-28',
            end_date                => '2011-06-30',
            cold_water_start_amount => '33',
            cold_water_end_amount   => '39',
            hot_water_start_amount  => '20',
            hot_water_end_amount    => '22',
        }
    );

    my $metering12 = Meter::Meterings->insert(
        {   appartment              => $appartment1,
            start_date              => '2011-06-30',
            end_date                => '2011-07-26',
            cold_water_start_amount => '39',
            cold_water_end_amount   => '41',
            hot_water_start_amount  => '22',
            hot_water_end_amount    => '25',
        }
    );

    # user2 has no meterings

    # user3's meterings
    my $metering31 = Meter::Meterings->insert(
        {   appartment              => $appartment3,
            start_date              => '2011-05-25',
            end_date                => '2011-06-25',
            cold_water_start_amount => '10',
            cold_water_end_amount   => '20',
            hot_water_start_amount  => '15',
            hot_water_end_amount    => '25',
        }
    );

    my $metering32 = Meter::Meterings->insert(
        {   appartment              => $appartment3,
            start_date              => '2011-06-25',
            end_date                => '2011-07-25',
            cold_water_start_amount => '20',
            cold_water_end_amount   => '30',
            hot_water_start_amount  => '25',
            hot_water_end_amount    => '35',
        }
    );

    my $metering33 = Meter::Meterings->insert(
        {   appartment              => $appartment3,
            start_date              => '2011-07-25',
            end_date                => '2011-08-25',
            cold_water_start_amount => '30',
            cold_water_end_amount   => '40',
            hot_water_start_amount  => '35',
            hot_water_end_amount    => '45',
        }
    );

    # check user3's data objects

    Readonly my $USERNAME => 'user3';
    Readonly my $PASSWORD => 'password3';

    my $user = Meter::Users->retrieve(
        username => $USERNAME,
        password => $PASSWORD,
    );

    ok( $user, "Find user '$USERNAME'" );
    is( $user->appartment(), $appartment3, q{Check user's appartment} );
    is( $user->appartment()->house()->address(),
        $house2->address(), q{Check user's house address} );

    my @meterings = sort { $a->start_date() <=> $b->start_date() }
        $user->appartment()->meterings();
    ### got meterings: @meterings

    is_deeply(
        [@meterings],
        [ $metering31, $metering32, $metering33 ],
        q{Check user's meterings}
    );

    # delete user and check that all user's elements are also removed
    my $user1_id = $user1->user();
    ### user1_id: $user1_id

    $user1->delete();

    foreach my $table qw( users appartments meterings ) {
        not_row_ok(
            table => 'users',
            where => [ user_id => $user1_id ],
            label =>
                "Check NO database row for user_id='$user1_id' in '$table' table",
        );
    }

    return;
}

sub run_tests {
    init_tmp_db();

    test_common_case();

    return;
}

run_tests();
